package registration;

import static org.junit.Assert.*;

import java.sql.SQLException;
import java.util.*;

import msg.EventMessage;

import org.junit.Test;

import user.User;

import common.DBTest;
import common.dal.Transaction;
import common.exceptions.*;
import common.interfaces.IPersistent;

@SuppressWarnings({"javadoc"})
public class DBEventRegisterTest extends DBTest {
	private static DBEventRegister	$;
	
	@Override
	protected IPersistent setPersistent(Transaction t) {
		$ = new DBEventRegister(t);
		return $;
	}
	
	@Override
	protected IPersistent getPersistent() {
		return $;
	}
	
	private void registerUserToEvent() throws SQLException, InvalidEventException, InvalidUserException {
		$.register(getUser(), getEvent());
	}
	
	@Test(expected = InvalidUserException.class)
	public void testRegisterBadUser() throws Exception {
		$.register(getFakeUser(), getEvent());
	}
	
	@Test(expected = InvalidEventException.class)
	public void testRegisterBadEvent() throws Exception {
		$.register(getUser(), getFakeEvent());
	}
	
	@Test(expected = InvalidUserException.class)
	public void testUnregisterBadUser() throws Exception {
		$.register(getFakeUser(), getEvent());
	}
	
	@Test(expected = InvalidEventException.class)
	public void testUnregisterBadEvent() throws Exception {
		$.register(getUser(), getFakeEvent());
	}
	
	@Test
	public void testRegister() throws Exception {
		assertTrue($.register(getUser(), getEvent()));
		assertFalse($.register(getUser(), getEvent()));
	}
	
	@Test
	public void testUnregister() throws Exception {
		assertTrue($.register(getUser(), getEvent()));
		assertTrue($.unregister(getUser(), getEvent()));
		assertFalse($.unregister(getUser(), getEvent()));
	}
	
	@Test(expected = InvalidUserException.class)
	public void testRemoveUserInvalid() throws Exception {
		$.removeAllUserRegisrations(getFakeUser());
	}
	
	@Test
	public void testRemoveUser() throws Exception {
		registerUserToEvent();
		$.removeAllUserRegisrations(getUser());
		assertTrue($.register(getUser(), getEvent()));
	}
	
	@Test(expected = InvalidEventException.class)
	public void testRemoveEventInvalid() throws Exception {
		$.removeAllEventRegisrations(getFakeEvent());
	}
	
	@Test
	public void testRemoveEvent() throws Exception {
		registerUserToEvent();
		$.removeAllEventRegisrations(getEvent());
		assertTrue($.register(getUser(), getEvent()));
	}
	
	@Test(expected = InvalidEventException.class)
	public void testGetCountInvalid() throws Exception {
		$.getTotalRegisteredTo(getFakeEvent());
	}
	
	@Test()
	public void testGetCount() throws Exception {
		assertEquals(0, $.getTotalRegisteredTo(getEvent()));
		registerUserToEvent();
		assertEquals(1, $.getTotalRegisteredTo(getEvent()));
	}
	
	@Test(expected = InvalidUserException.class)
	public void testGetAllEventsInvalidUser() throws Exception {
		$.getAllEventRegisteredByUser(getFakeUser());
	}
	
	@Test
	public void testGetAllEvents() throws Exception {
		assertTrue($.getAllEventRegisteredByUser(getUser()).isEmpty());
		registerUserToEvent();
		Set<EventMessage> expected = new HashSet<>(Arrays.asList(getEvent()));
		assertEquals(expected, new HashSet<>($.getAllEventRegisteredByUser(getUser())));
	}
	
	@Test(expected = InvalidEventException.class)
	public void testGetAllUsersInvalidEvent() throws Exception {
		$.getAllUsersRegisteredToEvent(getFakeEvent());
	}
	
	@Test
	public void testGetAllUsers() throws Exception {
		assertTrue($.getAllUsersRegisteredToEvent(getEvent()).isEmpty());
		registerUserToEvent();
		Set<User> expected = new HashSet<>(Arrays.asList(getUser()));
		assertEquals(expected, new HashSet<>($.getAllUsersRegisteredToEvent(getEvent())));
	}
}
